package com.chenyun.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenyun.boot.datasource.page.PageUtils;
import com.chenyun.common.annotation.Page;
import com.chenyun.common.constants.SysConstants;
import com.chenyun.common.exceptions.BusinessException;
import com.chenyun.common.utils.ValidationUtils;
import com.chenyun.common.vo.PageResult;
import com.chenyun.system.mapper.SysTenantMapper;
import com.chenyun.system.model.SysRole;
import com.chenyun.system.model.SysTenant;
import com.chenyun.system.model.SysTenantType;
import com.chenyun.system.model.SysUser;
import com.chenyun.system.param.TenantParam;
import com.chenyun.system.param.TenantQueryPage;
import com.chenyun.system.service.ISysRoleService;
import com.chenyun.system.service.ISysTenantService;
import com.chenyun.system.service.ISysTenantTypeService;
import com.chenyun.system.service.ISysUserService;
import com.chenyun.tenant.TenantContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 租户
 *
 * @author: lonni
 * @CreateTime: 2023-12-06  20:11
 * @Description:
 */
@Service
@Slf4j
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {
;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysTenantTypeService typeService;

    SysTenantType checkTenant(TenantParam param) {
        //设置不使用租户
        TenantContext.me.setIgnoreTenant(true);
        ValidationUtils.validateObject(param);
        if (param.getId() == null) {
            if (StrUtil.isBlank(param.getNickName())) {
                throw new BusinessException("请输入用户名称");
            }
            if (StrUtil.isBlank(param.getUserName())) {
                throw new BusinessException("请输入联系人名称");
            }
            if (StrUtil.isBlank(param.getPassword())) {
                throw new BusinessException("请输入租户密码");
            }
        }
        SysTenantType tenantType = typeService.checkType(param.getTypeId());

        //检查唯一
        SysTenant tenant = this.getOne(Wrappers.lambdaQuery(SysTenant.class)
                .eq(SysTenant::getName, param.getName())
        );
        if (param.getId() == null && tenant != null) {
            throw new BusinessException("租户已存在!");
        }
        if (param.getId() != null && tenant != null && param.getId().intValue() != tenant.getId().intValue()) {
            throw new BusinessException("租户已存在!");
        }

        return tenantType;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTenant(TenantParam param) {
        SysTenantType tenantType = checkTenant(param);
        SysTenant sysTenant = BeanUtil.copyProperties(param, SysTenant.class);
        boolean save = this.save(sysTenant);
        //保存租户成功,添加系统用户和角色和菜单权限
        SysUser sysUser = new SysUser();
        sysUser.setNickName(param.getNickName());
        sysUser.setUserName(param.getUserName());
        sysUser.setPhonenumber(param.getMobile());
        sysUser.setPassword(param.getPassword());
        sysUser.setUserType("00");
        sysUser.setTenantId(sysTenant.getId().toString());


        SysRole sysRole = new SysRole();
        sysRole.setRoleKey(SysConstants.TENANT_DEFAULT_ROLE);
        sysRole.setRoleName(SysConstants.TENANT_DEFAULT_ROLE_NAME);
        sysRole.setRemark("系统自动添加");
        sysRole.setTenantId(sysTenant.getId().toString());
        sysRole.setRoleSort("1");


        List<String> strings = tenantType.getMenuIds();
        Long[] ids = new Long[strings.size()];
        AtomicInteger index = new AtomicInteger(0);
        strings.forEach(p -> {
            int andIncrement = index.getAndIncrement();
            ids[andIncrement] = Long.valueOf(p);
        });
        sysRole.setMenuIds(ids);
        userService.insertUser(sysUser);
        //添加角色
        roleService.insertRole(sysRole);
        SysUser saveUser = userService.selectUserByUserName(sysUser.getUserName());
        List<SysRole> sysRoles = roleService.selectRoleList(sysRole);
        //添加用户和角色绑定
        userService.insertUserRole(Long.valueOf(saveUser.getUserId()), sysRoles.get(0).getRoleId());

        //添加成功,修改租户的id
        SysTenant tenant = this.getTenant(sysTenant.getId());
        tenant.setUserId(String.valueOf(saveUser.getUserId()));
        this.saveOrUpdate(tenant);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateTenant(TenantParam param) {
        //设置不使用租户
        TenantContext.me.setIgnoreTenant(true);
        SysTenant sysTenant = this.getById(param.getId());
        if (sysTenant == null) {
            throw new BusinessException("租户不存在!");
        }
        SysTenantType sysTenantType = this.checkTenant(param);
        BeanUtil.copyProperties(param, sysTenant);
        this.saveOrUpdate(sysTenant);
        if (!param.getMobile().equals(sysTenant.getMobile())) {//修改手机号
            SysUser sysUser = userService.selectUserById(Long.valueOf(sysTenant.getUserId()));
            sysUser.setPhonenumber(param.getMobile());
            userService.updateUser(sysUser);
        }
        return true;
    }

    @Override
    public Boolean delTenant(List<Integer> ids) {
        List<SysTenant> sysTenants = this.listByIds(ids);
        if (CollectionUtil.isNotEmpty(sysTenants)) {
            //查询是否包含默认租户
            sysTenants.stream().filter(p -> p.getTypeId().equals(SysConstants.DEFAULT_TENANT_ID)).findAny().ifPresent(p -> {
                throw new BusinessException("租户[" + p.getName() + "]属于默认租户,不能删除");
            });
            return this.removeByIds(ids);
        }
        return false;

    }

    @Override
    @Page
    public PageResult pageList(TenantQueryPage param) {
        //设置不使用租户
        TenantContext.me.setIgnoreTenant(true);
        List<TenantParam> tenantParams = this.baseMapper.pageList(param);
        return PageUtils.getPageHelperByList(tenantParams);
    }


    @Override
    public SysTenant getTenant(Integer id) {
        return this.getById(id);
    }


    /**
     * 判断是否是默认租户
     *
     * @param id
     * @return
     */
    private static boolean isDefaultTenant(Integer id) {
        return Objects.equals(id, SysConstants.DEFAULT_TENANT_ID);
    }
}
